﻿
Imports AutoCAD

''' <summary>
''' CAD绘制孔服务2
''' </summary>
Public Class CadDrawHole2ServiceImpl
    Private ms As IAcadBlock
    Private cadUcsService As ICadUcsService = New CadUcsServiceImpl
    Private evalService As IEvalService = New EvalServiceImpl

    ''' <summary>
    ''' 绘制孔对象
    ''' </summary>
    ''' <param name="dr"></param>
    ''' <returns></returns>
    Public Function drawHelo(ByRef dr As DataRow) As AcadEntity
        ' 设置参数
        Dim hole_line_id As Integer = dr("hole_line_id")
        Dim hole_head_id As Integer = dr("hole_head_id")
        Dim name As String = dr("name")
        Dim inhibition As Boolean = dr("inhibition")
        Dim diameter As Double = dr("diameter")
        Dim depth As Double = dr("depth")
        Dim px As Double = dr("px")
        Dim py As Double = dr("py")
        Dim pz As Double = dr("pz")
        Dim rx As Double = dr("rx")
        Dim ry As Double = dr("ry")
        Dim rz As Double = dr("rz")
        Dim layout As String = dr("layout")
        ' 绘制图形
        Dim ucs As AcadUCS = cadUcsService.addUcs(ms.Document, "tempUcs")
        Dim circle As AcadCircle
        Dim arr(0) As AcadEntity
        Dim region As Object
        Dim solid As Acad3DSolid
        With ms
            circle = .AddCircle(cadUcsService.getZeroPoint, diameter / 2) '在零点位置绘制圆形
            arr(0) = circle
            region = .AddRegion(arr) '创建面域
            solid = .AddExtrudedSolid(region(0), depth, 0) '创建实体
            solid.TransformBy(cadUcsService.rotateUcs(ucs, rx, ry, rz).GetUCSMatrix) '应用旋转后的UCS矩阵
            solid.Move(cadUcsService.getZeroPoint, New Double() {px, py, pz})
            solid.Layer = layout

            circle.Delete()
            region(0).Delete
        End With
        ' 返回实体
        Return solid
    End Function

    ''' <summary>
    ''' 绘制孔对象
    ''' </summary>
    ''' <param name="dt"></param>
    ''' <returns></returns>
    Public Function drawHelo(ByRef dt As DataTable) As List(Of AcadEntity)
        ' 检查
        If ms Is Nothing Then
            MsgBox("drawHelo:无效绘图空间")
            Return Nothing
        End If
        If dt Is Nothing Then
            MsgBox("drawHelo:无效绘图数据")
            Return Nothing
        End If
        ' 绘制孔
        Dim lt As New List(Of AcadEntity)
        For Each dr As DataRow In dt.Rows
            If Not dr("inhibition") Then lt.Add(drawHelo(dr))
        Next dr
        ' 返回列表
        Return lt
    End Function

    Public Function buildDataTable() As DataTable
        Dim dt As New DataTable
        With dt.Columns
            .Add("hole_line_id", GetType(Integer))
            .Add("hole_head_id", GetType(Integer))
            .Add("name", GetType(String))
            .Add("inhibition", GetType(Boolean))
            .Add("diameter", GetType(Double))
            .Add("depth", GetType(Double))
            .Add("px", GetType(Double))
            .Add("py", GetType(Double))
            .Add("pz", GetType(Double))
            .Add("rx", GetType(Double))
            .Add("ry", GetType(Double))
            .Add("rz", GetType(Double))
            .Add("layout", GetType(String))
        End With
        Return dt
    End Function

    ''' <summary>
    ''' 获取孔位绘图数据
    ''' </summary>
    ''' <param name="holeLineTable"> 钻孔行数据表 </param>
    ''' <param name="[property]"> 钻孔控制参数字典 </param>
    ''' <returns></returns>
    ''' <remarks> 行数据表中的各属性表达式, 仅会仅用到钻孔控制参数 </remarks>
    Public Function getDrawData(ByRef holeLineTable As DataTable, ByRef [property] As Dictionary(Of String, Object))
        Dim data As DataTable = holeLineTable '孔位数据行
        Dim result As DataTable = buildDataTable() '声明钻孔数据表

        ' 在当前环节, 行数据的计算仅用到holePorperty
        Dim newDataRow As DataRow
        For Each dr As DataRow In data.Rows '遍历行数据
            newDataRow = result.NewRow
            For Each dc As DataColumn In data.Columns '遍历每一个属性
                Dim colName As String = dc.ColumnName
                newDataRow(colName) = evalService.AnalyzeExpressions_ByDict(dr(colName), [property]) '计算每个孔属性的表达式
            Next dc
            result.Rows.Add(newDataRow)
        Next dr
        Return result
    End Function


    ''' <summary>
    ''' [未测试] 获取孔控制属性字典
    ''' </summary>
    ''' <param name="holePropertyExpressionTable"> 钻孔控制参数表达式表, 即未处理数据 </param>
    ''' <param name="bboxProperty"> BBox属性字典, 即已经处理的结果表 </param>
    ''' <returns></returns>
    ''' <remarks> 从远程获取到孔控制属性表 holePropertyExpressionTable, 经过此函数加工, 将表达式转为值并存入字典中, 最终返回字典  </remarks>
    Public Function getHolePropertyDict(ByRef holePropertyExpressionTable As DataTable, ByRef bboxProperty As Dictionary(Of String, Object)) As Dictionary(Of String, Object)
        Dim result As New Dictionary(Of String, Object)
        For Each dr As DataRow In holePropertyExpressionTable.Rows
            Dim propertyName As String = dr("name")
            Dim propertyExpression As String = dr("expression")
            Dim propertyValue As Object = evalService.AnalyzeExpressions_ByDict(propertyExpression, bboxProperty) '计算每个孔属性的表达式
            result.Add(propertyName, propertyValue)
        Next dr
        Return result
    End Function


#Region "TEST"

    ' 从数据库中获取数据, 并在cad中绘制图形
    Public Function test2() As DataTable
        ' 获得远程数据
        Dim mysqlService As IMySqlService = New MySqlServiceImpl
        Dim holeHeadId As Integer = 1
        mysqlService.connection()
        Dim sql As String
        sql = $"select * from hole_line where hole_head_id = {holeHeadId}"
        Dim holeLineTable As DataTable = mysqlService.select(sql)
        sql = $"select * from hole_property where hole_head_id = {holeHeadId}"
        Dim holeProperty As DataTable = mysqlService.select(sql)
        Dim dict As New Dictionary(Of String, Object)
        For Each dr As DataRow In holeProperty.Rows
            dict.Add(dr("name"), dr("expression"))
        Next

        ' 获取绘图数据
        Dim data As DataTable = getDrawData(holeLineTable, dict)

        ' 执行绘图
        Dim cadApplicationService As ICadApplicationService = New CadApplicationServiceImpl
        Dim doc As AcadDocument = cadApplicationService.GetActiveDocument
        Dim cadDrawHole As New CadDrawHole2ServiceImpl
        Me.ms = doc.ModelSpace
        drawHelo(data) ' 绘制图形

        Return data
    End Function


    ' 使用 getTestData 构建测试数据,  并在cad中绘制图形
    Public Sub test()
        Dim cadApplicationService As ICadApplicationService = New CadApplicationServiceImpl
        Dim doc As AcadDocument = cadApplicationService.GetActiveDocument
        Dim cadDrawHole As New CadDrawHole2ServiceImpl
        Me.ms = doc.ModelSpace
        Dim dt As DataTable = getTestData()
        drawHelo(dt) ' 绘制图形
    End Sub


    Public Function getTestData() As DataTable
        Dim layout As String = "孔位"
        Dim dt As New DataTable
        With dt.Columns
            .Add("hole_line_id", GetType(Integer))
            .Add("hole_head_id", GetType(Integer))
            .Add("name", GetType(String))
            .Add("inhibition", GetType(Boolean))
            .Add("diameter", GetType(Double))
            .Add("depth", GetType(Double))
            .Add("px", GetType(Double))
            .Add("py", GetType(Double))
            .Add("pz", GetType(Double))
            .Add("rx", GetType(Double))
            .Add("ry", GetType(Double))
            .Add("rz", GetType(Double))
            .Add("layout", GetType(String))
        End With

        Dim dr As DataRow

        dr = dt.NewRow()
        dr("hole_line_id") = 1
        dr("hole_head_id") = 1
        dr("name") = "水平孔_左1"
        dr("inhibition") = False
        dr("diameter") = 8
        dr("depth") = 34
        dr("px") = 0
        dr("py") = -34
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = 90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 2
        dr("hole_head_id") = 1
        dr("name") = "水平孔_左2"
        dr("inhibition") = False
        dr("diameter") = 8
        dr("depth") = 34
        dr("px") = 0
        dr("py") = -34 - 32
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = 90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 3
        dr("hole_head_id") = 1
        dr("name") = "水平孔_右1"
        dr("inhibition") = False
        dr("diameter") = 8
        dr("depth") = 34
        dr("px") = 900
        dr("py") = -34
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = -90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 4
        dr("hole_head_id") = 1
        dr("name") = "水平孔_右2"
        dr("inhibition") = False
        dr("diameter") = 8
        dr("depth") = 34
        dr("px") = 900
        dr("py") = -34 - 32
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = -90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 5
        dr("hole_head_id") = 1
        dr("name") = "正面_左1"
        dr("inhibition") = False
        dr("diameter") = 15
        dr("depth") = 14
        dr("px") = 34
        dr("py") = -34
        dr("pz") = 18
        dr("rx") = 180
        dr("ry") = 0
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 6
        dr("hole_head_id") = 1
        dr("name") = "正面_左2"
        dr("inhibition") = False
        dr("diameter") = 15
        dr("depth") = 14
        dr("px") = 34
        dr("py") = -34 - 32
        dr("pz") = 18
        dr("rx") = 180
        dr("ry") = 0
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 7
        dr("hole_head_id") = 1
        dr("name") = "正面_右1"
        dr("inhibition") = False
        dr("diameter") = 15
        dr("depth") = 14
        dr("px") = 900 - 34
        dr("py") = -34
        dr("pz") = 18
        dr("rx") = 180
        dr("ry") = 0
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 8
        dr("hole_head_id") = 1
        dr("name") = "正面_右2"
        dr("inhibition") = False
        dr("diameter") = 15
        dr("depth") = 14
        dr("px") = 900 - 34
        dr("py") = -34 - 32
        dr("pz") = 18
        dr("rx") = 180
        dr("ry") = 0
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)


        dr = dt.NewRow()
        dr("hole_line_id") = 1
        dr("hole_head_id") = 1
        dr("name") = "水平孔_左1"
        dr("inhibition") = False
        dr("diameter") = 10
        dr("depth") = 12
        dr("px") = 0
        dr("py") = -34
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = -90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 2
        dr("hole_head_id") = 1
        dr("name") = "水平孔_左2"
        dr("inhibition") = False
        dr("diameter") = 10
        dr("depth") = 12
        dr("px") = 0
        dr("py") = -34 - 32
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = -90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 3
        dr("hole_head_id") = 1
        dr("name") = "水平孔_右1"
        dr("inhibition") = False
        dr("diameter") = 10
        dr("depth") = 12
        dr("px") = 900
        dr("py") = -34
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = 90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("hole_line_id") = 4
        dr("hole_head_id") = 1
        dr("name") = "水平孔_右2"
        dr("inhibition") = False
        dr("diameter") = 10
        dr("depth") = 12
        dr("px") = 900
        dr("py") = -34 - 32
        dr("pz") = 9
        dr("rx") = 0
        dr("ry") = 90
        dr("rz") = 0
        dr("layout") = layout
        dt.Rows.Add(dr)

        Return dt
    End Function

#End Region

End Class
